import fetch from 'dva/fetch';
import { API_ROOT } from 'config';
import { message } from 'antd';
import auth from 'utils/auth';
import { routerRedux } from 'dva/router';

function checkStatus(response) {
  if (response.status >= 200 && response.status < 300) {
    return response;
  }

  if (response.status === 401) {
    console.log('location: ', window.location);
    // g_app._store.dispatch(routerRedux.push('/login'));
    // return;
  }

  const error = new Error(response.statusText);
  error.response = response;
  throw error;
}

function buildQueryString(params) {
  if (!params) return '';

  const keys = Object.keys(params);
  if (keys.length === 0) return '';

  const components = keys.map(
    key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`
  );

  return `?${components.join('&')}`;
}

function prepareRequest(url, options) {
  let { method, body } = options;
  const isNotGet = method.toUpperCase() !== 'GET';

  const queryString = isNotGet ? '' : buildQueryString(body);
  body = isNotGet ? JSON.stringify(body) : null;

  const headers = {
    Authorization: `Bearer ${auth.getAccessToken()}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  };

  // dev本地开发：使用mock数据，直接/user-api/xxxx请求
  // 测试和正式环境：加上域名直接访问api接口，绕过proxy
  url += queryString;
  if (process.env.UMI_ENV !== 'prod') {
    url = API_ROOT + url;
  }

  const timeout = 4;
  const mode = 'cors';
  options = { ...options, body, headers, mode, timeout };

  return { url, options };
}

/**
 * Requests a URL, returning a promise.
 *
 * @param  {string} url       The URL we want to request
 * @param  {object} [options] The options we want to pass to "fetch"
 * @return {object}           An object containing either "data" or "err"
 */
export default async function request(uri, params) {
  const { url, options } = prepareRequest(uri, params);

  const response = await fetch(url, options);

  checkStatus(response);

  const result = await response.json();
  const { code, msg } = result;

  if (code) {
    message.error(msg);
  } else if (options.method !== 'GET') {
    message.success('操作成功');
  }

  return result;
}
